<?php
/** 
 * php锁机制
 * @link http://www.tpframe.com/
 * @copyright Copyright (c) 2017 TPFrame Software LLC
 * @author 510974211@qq.com
    要取得共享锁定（读取的程序），将 lock 设为 LOCK_SH（PHP 4.0.1 以前的版本设置为 1）。
    要取得独占锁定（写入的程序），将 lock 设为 LOCK_EX（PHP 4.0.1 以前的版本中设置为 2）。
    要释放锁定（无论共享或独占），将 lock 设为 LOCK_UN（PHP 4.0.1 以前的版本中设置为 3）。
    如果不希望 flock() 在锁定时堵塞，则给 lock 加上 LOCK_NB（PHP 4.0.1 以前的版本中设置为 4）。
 */
namespace tpfcore\lock;
use tpfcore\base\ILock;
class FileLock implements ILock
{

    private $_fp;

    private $_single;

    public function __construct($options=[])
    {
        if (isset($options['path']) && is_dir($options['path']))
        {
            $this->_lockPath = $options['path'].'/';
        }
        else
        {
            $this->_lockPath = '/tmp/';
        }
       
        $this->_single = isset($options['single'])?$options['single']:false;
    }

    public function getLock($key, $timeout=self::EXPIRE)
    {

        $file = md5(__FILE__.$key);

        $this->fp = fopen($this->_lockPath.$file.'.lock', "w+");

        if (true || $this->_single)
        {
            $op = LOCK_EX + LOCK_NB;
        }
        else
        {
            $op = LOCK_EX;
        }
        if (false == flock($this->fp, $op, true))
        {
            throw new Exception('failed');
        }
       
	    return true;
    }

    public function releaseLock($key)
    {
        flock($this->fp, LOCK_UN);

        fclose($this->fp);
    }
}